package com.ng.sys.service.impl;

import java.util.Arrays;
import java.util.Date;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ng.common.cache.annotation.TrCacheEvict;
import com.ng.common.exception.NgException;
import com.ng.common.service.CacheServiceImpl;
import com.ng.common.utils.Constant;
import com.ng.common.utils.DesUtils;
import com.ng.common.utils.MD5Utils;
import com.ng.common.utils.PageUtils;
import com.ng.common.utils.Query;
import com.ng.common.validator.Assert;
import com.ng.config.SysConfig;
import com.ng.sys.dao.SysUserDao;
import com.ng.sys.entity.SysUserEntity;
import com.ng.sys.service.SysMenuService;
import com.ng.sys.service.SysUserRoleService;
import com.ng.sys.service.SysUserService;
import com.ng.sys.service.SysUserTokenService;


/**
 * 系统用户
 * 
 * @author lyf
 * @date 2016年9月18日 上午9:46:09
 */
@Service
public class SysUserServiceImpl extends CacheServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	@Autowired
	private SysUserRoleService sysUserRoleService;
  
    
    @Autowired
    private SysMenuService menuService ;
    

    @Autowired
    private SysUserTokenService sysUserTokenService ;
    
    @Autowired
    private SysConfig config;
	
	@Override
	public PageUtils queryPage(SysUserEntity entity , PageUtils page) {
		String username = entity.getUsername();
		 
		IPage<SysUserEntity> ipage = this.page(
			new Query<SysUserEntity>(page).getPage(),
			new QueryWrapper<SysUserEntity>()
				.like(StringUtils.isNotBlank(username),"username", username)
				 
				.orderByAsc("user_no")
		);

		return new PageUtils(ipage);
	}

	
	
	

	@Override 
	public SysUserEntity queryByUserNo(String userNo) {
 
		if(userNo.equals(Constant.SUPER_ADMIN)) {
			return config.getAdminUser();
		}
		
		QueryWrapper<SysUserEntity> query = new QueryWrapper<>();
		query.eq("user_no", userNo);
		
		SysUserEntity sae = getOne(query);//baseMapper.queryByUserCode(code);
 
		
		return sae ;
	}
 
	@Transactional
    @Override
	public boolean saveUser(SysUserEntity user) {


        if (uniquenessCheckUserNo(user.getUserNo(), null)) {
            throw new NgException("用户账号已存在");
        }
        if (uniquenessCheckUsername(user.getUsername(), null)) {
            throw new NgException("用户名已存在");
        }
		
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		String pass = MD5Utils.md5Pass(user.getPassword(), salt);
		user.setPassword(pass);
		user.setSalt(salt);
		boolean s = this.save(user);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
		 
		 
		return s ;
	}

	@Override
	@Transactional
	@TrCacheEvict("#user.userId" )
	public void update(SysUserEntity user) {
		
	    // 检查用户名词是否重复
        if (uniquenessCheckUserNo(user.getUserNo(), user.getUserId())) {
            throw new NgException("用户账号已存在");
        }
        if (uniquenessCheckUsername(user.getUsername(), user.getUserId())) {
            throw new NgException("用户名已存在");
        }
		
		if(StringUtils.isBlank(user.getPassword())){
			user.setPassword(null);
		}else{
			//密码解密
			String pass = DesUtils.desEncrypt(user.getPassword()) ;// RsaUtils.decryptByPrivateKey(user.getPassword());
			if(pass != null && !pass.isEmpty()) {
				String md5pass = MD5Utils.md5Pass(pass, user.getSalt());
				user.setPassword(md5pass);
			}
				
			else {
				user.setPassword(null);
			}
		}
		
		 
		this.baseMapper.updateUser(user);
		
		 // 清理缓存 
        clearUserCache(user.getUserId() ,user.getStatus() == 0);
		
		//检查角色是否越权
		checkRole(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());


	}

	  /**
     * 清理用户的缓存
     *
     * @param userId
     * @clearAll 是否清理用户的的登录token缓存
     */
    private void clearUserCache(String userId, boolean clearAll) {
        // token_user_
    	 // 清理用户权限和菜单
        menuService.clearUserPerms(userId);
    	if(clearAll) {
    		 sysUserTokenService.clearUserTokenCache(userId);
    	}  
        
         
    }

	@Override
	@TrCacheEvict
	public void deleteBatch(String[] userIds) {
		 
        this.removeByIds(Arrays.asList(userIds));
        for (String userId : userIds) {
            // 清理缓存
            clearUserCache(userId , true);
        }
	}

	@Override
	@TrCacheEvict("#userId")
	public boolean updatePassword(String userId, String password, String newPassword) {
		
		boolean update = true ;
    	if(userId.equals(Constant.SUPER_ADMIN)) {
    		
    		// 判断原密码
    		if(!password.equals(config.getAdminUser().getPassword())) {
    			return false;
    		}
    		
    		config.updatePassword(newPassword);
    	} else {
    		SysUserEntity userEntity = new SysUserEntity();
            userEntity.setPassword(newPassword);
            update = this.update(userEntity,
                    new QueryWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));

    	}
		
    	 // 清理缓存
        if(update)
        	clearUserCache(userId, true);

        return update;
	}
	
	/**
	 * 检查角色是否越权
	 */
	private void checkRole(SysUserEntity user){
		/*if(user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
			return;
		}*/
		//如果不是超级管理员，则需要判断用户的角色是否自己创建
		/*if(user.getCreateUserId().equals(Constant.SUPER_ADMIN)){
			return ;
		}*/
		
		/*//查询用户创建的角色列表
		List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

		//判断是否越权
		if(!roleIdList.containsAll(user.getRoleIdList())){
			throw new RRException("新增用户所选角色，不是本人创建");
		}*/
	}

	@Override
	@TrCacheEvict("#userId")
	public boolean resetPass(String userId, String newPass) {
		
		// 判断越权
    	SysUserEntity user = getById(userId);
    	Assert.isNull(user, "用户不存在");
    	
		baseMapper.resetPass(userId, newPass);

		// 清理该用户的缓存
		clearUserCache(userId, true);

		
		return true;
	}

  

	@Override
	//@TrCache(value="#userId")
	public SysUserEntity getById(String userId) {
		if(userId.equals(Constant.SUPER_ADMIN)) {
			return config.getAdminUser();
		}
		return super.getById(userId);
	}
	
 
	public boolean uniquenessCheckUserNo(String userNo, String userId) {
		
		if(userNo.equals(Constant.SUPER_ADMIN)) {
			return true ;
		}
		
        QueryWrapper<SysUserEntity> query = new QueryWrapper<>();
        query.eq("user_no", userNo);

        query.ne(StringUtils.isNotBlank(userId), "user_id", userId);

        return count(query) > 0;
    }


    public boolean uniquenessCheckUsername(String username, String userId) {

        QueryWrapper<SysUserEntity> query = new QueryWrapper<>();
        query.eq("username", username);

        query.ne(StringUtils.isNotBlank(userId), "user_id", userId);

        return count(query) > 0;
    }


 

 
	
}
